﻿using LinqKit;
using Shop.Collect;
using Shop.ExtendService;
using Shop.LocalEvent;
using Shop.Model.DB;
using Shop.Model.Spec;
using Shop.RemoteModel.GoodsSpec.Model;
using Shop.Service.Helper;
using Shop.Service.Interface;
using WeDonekRpc.Client;
using WeDonekRpc.Helper;

namespace Shop.Service.lmpl
{
    internal class SpecGroupService : ISpecGroupService
    {
        private readonly ISpecGroupCollect _SpecGroup;
        private readonly IFileService _File;
        private readonly IGoodsSkuCollect _GoodsSku;
        private readonly IGoodsSkuStateCollect _SkuState;
        public SpecGroupService (ISpecGroupCollect specGroup,
            IGoodsSkuStateCollect skuState,
            IFileService file,
            IGoodsSkuCollect sku)
        {
            this._SkuState = skuState;
            this._GoodsSku = sku;
            this._File = file;
            this._SpecGroup = specGroup;
        }
        public void DeleteSpec (long specId)
        {
            DBGoodsSpec spec = this._SpecGroup.GetSpec(specId);
            this._SpecGroup.DeleteSpec(spec);
        }
        public void DeleteSpec (long goodsId, long[] specId)
        {
            this._SpecGroup.DeleteSpec(specId);
            new GoodsSpecEvent("Delete", goodsId, specId).AsyncPublic();
        }
        public void SyncSku (long goodsId)
        {
            GoodsSpecGroup[] group = this._SpecGroup.Gets(goodsId);
            new SpecGroupEvent(goodsId, group).AsyncPublic();
        }
        public bool SetSkuState (SkuStateSet state)
        {
            return this._SkuState.SetIsEnable(state);
        }
        public GoodsSpecSku[] GetSkuSpec (long goodsId)
        {
            GoodsSpecGroup[] group = this._SpecGroup.Gets(goodsId);
            if (group.IsNull())
            {
                return Array.Empty<GoodsSpecSku>();
            }
            GoodsSpecSku[] list = group.GetSpecSku();
            Dictionary<string, long> skuId = this._GoodsSku.GetsBySpecKey(goodsId);
            Dictionary<string, bool> state = this._SkuState.GetsSkuState(goodsId);
            list.ForEach(c =>
            {
                c.IsEnable = state.GetValueOrDefault(c.SpecKey, true);
                if (skuId.TryGetValue(c.SpecKey, out long id))
                {
                    c.SkuId = id;
                }
            });
            return list;
        }
        public bool SetSpec (long id, GoodsSpecSet set)
        {
            DBGoodsSpec spec = this._SpecGroup.GetSpec(id);
            string icon = spec.SpecIcon;
            if (this._SpecGroup.SetSpec(spec, new GoodsSpecSetDto
            {
                SpecIcon = set.SpecIcon,
                SpecName = set.SpecName
            }))
            {
                this._File.Sync(set.FileId, id, icon);
                return true;
            }
            return false;
        }
        public GoodsSpecGroup[] GetGroups (long goodsId)
        {
            return this._SpecGroup.Gets(goodsId);
        }

        public GoodsSpec AddSpec (GoodsSpecAdd spec)
        {
            GoodsSpecAddDto dto = spec.ConvertMap<GoodsSpecAdd, GoodsSpecAddDto>();
            long id = this._SpecGroup.AddSpec(dto);
            if (spec.FileId.HasValue)
            {
                this._File.Save(spec.FileId.Value, id);
            }
            GoodsSpec d = dto.ConvertMap<GoodsSpecAddDto, GoodsSpec>();
            d.Id = id;
            return d;
        }

        public long AddGroup (SpecGroupAdd datum)
        {
            return this._SpecGroup.AddGroup(datum);
        }

        public void DeleteGroup (long id)
        {
            DBGoodsSpecGroup group = this._SpecGroup.GetGroup(id);
            this._SpecGroup.DeleteGroup(group);
        }

        public bool SetGroup (long id, string name)
        {
            DBGoodsSpecGroup group = this._SpecGroup.GetGroup(id);
            return this._SpecGroup.SetGroup(group, name);
        }

        public Dictionary<long, int> SetGroupSort (long id, int sort)
        {
            DBGoodsSpecGroup group = this._SpecGroup.GetGroup(id);
            return this._SpecGroup.SetGroupSort(group, sort);
        }

        public Dictionary<long, int> SetSpecSort (long id, int sort)
        {
            DBGoodsSpec spec = this._SpecGroup.GetSpec(id);
            return this._SpecGroup.SetSpecSort(spec, sort);
        }
    }
}
